#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <signal.h>

#include <GeoIP.h>

#include "proxytest.h"
#include "thread_control.h"

void usage(char *argv);

inline void print_result(proxy_info_t *proxy_info)
{
	GeoIP * gi;
	gi = GeoIP_new(GEOIP_STANDARD);

	if(proxy_info->result.status.http)
	{
		printf("[OK] [%s] %s:%s dns:%dms con:%dms req:%dms res:%dms\n",
				GeoIP_country_code_by_addr(gi, proxy_info->request.host),
				proxy_info->request.host,
				proxy_info->request.port,
				time_taken(&proxy_info->result,tst_dns),
				time_taken(&proxy_info->result,tst_connect),
				time_taken(&proxy_info->result,tst_request),
				time_taken(&proxy_info->result,tst_response)
				);
	}
	else
	{
		printf("[error] [%s] %s:%s dns:%dms con:%dms req:%dms res:%dms\n",
				GeoIP_country_code_by_addr(gi, proxy_info->request.host),
				proxy_info->request.host,
				proxy_info->request.port,
				time_taken(&proxy_info->result,tst_dns),
				time_taken(&proxy_info->result,tst_connect),
				time_taken(&proxy_info->result,tst_request),
				time_taken(&proxy_info->result,tst_response)
				);
	}
	GeoIP_delete(gi);
	return;
}


int read_proxy_fp(proxy_info_t **proxy_info, int *proxy_count, FILE* fp)
{
	int step_len=64;
	char buf[1024];
	int flag_continue=1;
	int i=0;
	for((*proxy_count)=0,*proxy_info=NULL;flag_continue;)
	{
		proxy_info_t *tmp=NULL;
		tmp=malloc(((*proxy_count)+step_len)*sizeof(proxy_info_t));
		if(*proxy_info!=NULL)
		{
			bzero(tmp, ((*proxy_count)+step_len)*sizeof(proxy_info_t) );
			memcpy(tmp, *proxy_info, (*proxy_count)*sizeof(proxy_info_t) );
			free(*proxy_info);
		}
		*proxy_info=tmp;
		tmp=NULL;
		for(i=0;flag_continue&& i<step_len;i++)
		{
			if(fgets(buf,1024,fp)==NULL)
			{
				flag_continue=0;
				break;
			}
			if(index(buf,'\n')!=NULL)
			{
				*(index(buf,'\n'))='\0';
			}
			sscanf(buf,"%s %s",
					((*proxy_info)+(*proxy_count))->request.host,
					((*proxy_info)+(*proxy_count))->request.port);
			(*proxy_count)++;
		}
	}

	return 0;
}

int read_proxy_file(proxy_info_t **proxy_info, int *proxy_count, const char* input_file)
{
	FILE *fp=NULL;


	fp=fopen(input_file,"r");
	read_proxy_fp(proxy_info, proxy_count, fp);
	fclose(fp);
	return 0;
}


int read_proxy_host_port(proxy_info_t **proxy_info, int *proxy_count, char* proxy)
{
	return 0;
}


int main(int argc, char** argv)
{
	signal(SIGPIPE,SIG_IGN);
	int i,j,k;
	int proxy_count=0;
	proxy_info_t *proxy_info=NULL;
	int max_thread=20;
	char *input_file=NULL;
	char *proxy=NULL;

	i=j=k=0;

	static struct option opts[] = {
		{ "thread",	required_argument,	NULL,	'n'	},
		{ "input_file",	required_argument,	NULL,	'f'	},
		{ "proxy",	required_argument,	NULL,	'p'	},
		{ "help",	optional_argument,	NULL,	'h'	},
		{ NULL,		0,			NULL,	0	}
	};

	while ((i = getopt_long(argc, (void*)argv, "f:n:p:h::", opts, NULL)) != -1)
	{
		switch (i)
		{
			case 'n':
				max_thread=atoi(optarg);
				break;
			case 'f':
				j++;
				input_file=optarg;
				break;
			case 'p':
				k++;
				proxy=optarg;
				break;
			case 'h':
			default:
				usage(*(argv+0));
				return -1;
				break;
		}
	}

	if((j+k)==0)
	{
		printf("input_file(-f) or proxy(-p) need\n");
		usage(*(argv+0));
		return -1;
	}
	else if((j+k)>1)
	{
		printf("only 1 option can be choose from input_file(-f) and proxy(-p)\n");
		usage(*(argv+0));
		return -1;
	}
	else if(j==1)
	{
		read_proxy_file(&proxy_info,&proxy_count,input_file);
	}
	else if(k==1)
	{
		read_proxy_host_port(&proxy_info,&proxy_count,proxy);
	}
	else
	{
		printf("error\n");
		usage(*(argv+0));
		return -1;
	}






	thread_control_init(max_thread);

	for(i=0;i<proxy_count;i++)
	{
		thread_control_create((void*)http_proxy_test,(proxy_info+i));
	}

	thread_control_wait();

	for(i=0;i<proxy_count;i++)
	{
		print_result((proxy_info+i));
	}

	free(proxy_info);
	return 0;
}

void usage(char* argv)
{
	printf(
			"usage:\n"
			"\n"
			"\t%s [-a|--apply]|[-d|--delete]|[-r|--release]|[-t|--timeout second]|[-h|--help]\n"
			"\t\n"
			"\n"
			,argv
			);
}

